package com.fiveGroup.aspect;

import com.fiveGroup.pojo.OperationLog;
import com.fiveGroup.service.OperationLogService;
import com.fiveGroup.util.UserContextHolder;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * ClassName: LogAspect
 * Package:
 * Description
 * 日志切面类，用于记录操作日志
 * 记录管理员操作日志，包括操作动作、操作详情、操作时间、操作人ID等。
 *
 * @Aspect 切面类
 * @Author wen
 * @Create 2025/9/28 13:01
 * @Version 1.0
 */
@Aspect
@Component
@RequiredArgsConstructor
public class LogAspect {


    private final OperationLogService operationLogService;

    // 定义切点，拦截所有带有 @Log 注解的方法
    @Pointcut("@annotation(com.fiveGroup.annotation.Log)")
    public void logPointcut() {
    }

    // 定义环绕通知
    @Around("logPointcut() && @annotation(logAnnotation)")
    public Object logOperation(ProceedingJoinPoint joinPoint, com.fiveGroup.annotation.Log logAnnotation) throws Throwable {
        // 创建日志对象
        OperationLog log = new OperationLog();
        // 获取当前用户（示例，实际项目需从SecurityContext等获取）
        //获取当前用户Id
        //现在还没有登录功能，没有用户id,先设置为null
        try {
            log.setAdminId(UserContextHolder.getUserId());
        } catch (Exception e) {
            log.setAdminId(null);
        }
        //设置操作动作
        log.setAction(logAnnotation.action());
        //设置操作详情
        log.setDetail(logAnnotation.detail());
        //设置操作时间
        log.setCreatedAt(LocalDateTime.now());
        try {
            // 执行目标方法
            Object result = joinPoint.proceed();
            // 保存日志
            operationLogService.save(log);
            return result;
        } catch (Exception e) {
            // 如果方法执行出现异常，也记录日志
            log.setDetail(log.getDetail() + " - 执行异常: " + e.getMessage());
            try {
                operationLogService.save(log);
            } catch (Exception ex) {
                // 记录日志保存失败的情况，但不影响主流程
                ex.printStackTrace();
            }
            throw e;
        }
    }
}